#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cstring>
#include <unistd.h>
#include <vector>
#include "mutex.hpp"

namespace MypthreadModule
{
    using namespace MutexModule;

    /* 用于标识线程的name */
    static unsigned int number = 1;
    Mutex _mutex;        /* 互斥锁 */


    /* 用于标识当前线程的状态 */
    enum class STATUS
    {
        NEW,    /* 新创建 */
        RUNING, /* 运行中 */
        STOP    /* 暂停中 */
    };
    /* 包装器：包装回调函数 */
    using func_t = std::function<void()>;

    /* Thread类 */
    class Thread
    {
        /* 设置分离状态 */
        void EnableJoin()
        {
            _is_detachable = true;
        }

    public:
        Thread(func_t routine)                                     /* 缺省参数：回调函数 */
            : _tid(0), _pid(getpid()), _is_detachable(false) /* 默认不分离 */
              ,_routine(routine), _ret(nullptr), _status(STATUS::NEW)
        {
            /* 加锁 */
            {
                LockGuard lockguard(_mutex);
                _name = "thread-" + std::to_string(number++);
            }
        }

        /* 函数回调接口 */
        static void *Routine(void *args) /* 必须使用静态成员函数，否则带有this指针 */
        {
            Thread *t = static_cast<Thread *>(args);
            pthread_setname_np(t->_tid, t->_name.c_str());
            t->_routine(); /* 回调函数 */
            /* 自然结束更新状态 */
            t->_status = STATUS::STOP;
            /* 返回值 */
            return nullptr;
        }

        /* 创建线程 */
        bool Start()
        {
            /* 如果线程已经处于运行状态不要重新运行 */
            if (_status == STATUS::RUNING)
            {
                /* 属于重复运行情况 */
                return false;
            }

            /* 创建一个线程 */
            int n = pthread_create(&_tid, nullptr, Routine, static_cast<void *>(this));
            if (n != 0)
            {
                return false;
            }
            /* 更改状态为Runing */
            _status = STATUS::RUNING;

            /* 查看是否初始为分离状态,如果是进行分离 */
            if (_is_detachable == true)
                pthread_detach(_tid);
            return true;
        }

        /* 分离线程 */
        bool Detach()
        {
            if (_is_detachable == true)
            {
                /* 如果线程已经分离，不需要重新分离 */
                return false;
            }

            /* 进行分离 */
            /* 1. 分离 */
            int n = pthread_detach(_tid);
            if (n != 0)
            {
                return false;
            }
            /* 2. 设置分离状态 */
            EnableJoin();
            return true;
        }

        bool Join()
        {
            /* 如果线程已经分离,就不要join */
            if (_is_detachable == true)
            {
                return false;
            }

            int n = pthread_join(_tid, &_ret);
            if (n != 0)
            {
                return false;
            }
            /* 调整进程状态 */
            _status = STATUS::STOP;
            return true;
        }

        bool Cancel()
        {
            /* 取消的进程状态必须属于执行中的进程 */
            if (_status != STATUS::RUNING)
            {
                return false;
            }

            int n = pthread_cancel(_tid);
            if (n != 0)
            {
                return false;
            }
            /* 调整进程状态 */
            _status = STATUS::STOP;
            return true;
        }

        void *GetRet()
        {
            return _ret;
        }

        std::string Name()
        {
            return _name;
        }

        ~Thread()
        {
        }

    private:
        pthread_t _tid;      /* 线程tid */
        pid_t _pid;          /* 进程pid */
        std::string _name;   /* 线程name */
        bool _is_detachable; /* 线程是否分离 */
        func_t _routine;     /* 线程执行的函数 */
        void *_ret;          /* 用于获取返回值 */
        STATUS _status;      /* 线程状态 */
    };

}
